package com.ruoyi.share.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.google.gson.*;
import com.ruoyi.share.domain.ShareOrderForm;
import com.ruoyi.share.domain.ShareOrderGoodsRemarks;
import com.ruoyi.share.mapper.ShareOrderFormMapper;
import com.ruoyi.share.mapper.ShareOrderGoodsRemarksMapper;
import com.ruoyi.share.service.AliPayTGPService;
import com.ruoyi.share.config.TGPSecretkey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class AliPayTGPServiceImpl implements AliPayTGPService {
    @Autowired
    private ShareOrderFormMapper shareOrderFormMapper;
    @Autowired
    private ShareOrderGoodsRemarksMapper shareOrderGoodsRemarksMapper;
    @Override
    public Map toPayment(JSONObject jsonObject, HttpServletResponse response) throws IOException {
        // 返回对象
        Map res =new HashMap();
        //阿里配置类
        TGPSecretkey tgpSecretkey=new TGPSecretkey();
        Map<Object, Object> reqMap = new HashMap<>();
        //循环转换Json数据为map
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            reqMap.put(entry.getKey(), entry.getValue());
        }
        //创建订单对象
        ShareOrderForm shareOrderForm =new ShareOrderForm();
        //生成随机数
        Random random = new Random();
        //获取时间对象
        SimpleDateFormat allTime = new SimpleDateFormat("YYYYMMddHHmmSSS");
        //获取商品id
        shareOrderForm.setGoodsId(Long.parseLong(reqMap.get("goodsId").toString()));
        //获取订单号 当前时间+随机数
        String orderCode = "ZFB-"+allTime.format(new Date())+random.nextInt(10);
        shareOrderForm.setOrderCode(orderCode);
        //创建BigDeciaml 赋值money
        BigDecimal money =new BigDecimal(reqMap.get("money").toString());
        //订单对象Money赋值
        shareOrderForm.setMoney(money);
        //支付方式 //0，支付宝 ，1 微信， 3 银行卡
        shareOrderForm.setPaymentMethod(0);
        //支付状态 //0 未支付 ，1 已支付
        shareOrderForm.setPayStatus(0);

        //生成订单创建时间
        shareOrderForm.setCreateDate(new Date());
        /** 支付宝网关 **/
        String URL = "https://openapi.alipay.com/gateway.do";

        /** 应用id，如何获取请参考：https://opensupport.alipay.com/support/helpcenter/190/201602493024 **/
        final String APP_ID = tgpSecretkey.APP_ID;

        /** 应用私钥，如何获取请参考：https://opensupport.alipay.com/support/helpcenter/207/201602471154?ant_source=antsupport **/
        final String APP_PRIVATE_KEY = tgpSecretkey.APP_PRIVATE_KEY;

        /** 支付宝公钥，如何获取请参考：https://opensupport.alipay.com/support/helpcenter/207/201602487431 **/
        final String ALIPAY_PUBLIC_KEY = tgpSecretkey.ALIPAY_PUBLIC_KEY;


        /** 初始化 **/
        AlipayClient alipayClient = new DefaultAlipayClient(URL,APP_ID,APP_PRIVATE_KEY,"json","UTF-8",ALIPAY_PUBLIC_KEY,"RSA2");

        /** 实例化具体API对应的request类，类名称和接口名称对应，当前调用接口名称：alipay.trade.wap.pay（手机网站支付） **/
        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();

        /** 设置业务参数  **/
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();

        /** 商户订单号，商户自定义，需保证在商户端不重复，如：20200612000001 **/
        //赋值订单编号
        model.setOutTradeNo(orderCode);

        /** 销售产品码，固定值：QUICK_WAP_WAY **/
        model.setProductCode("QUICK_WAP_WAY");

        /** 订单标题 **/
        model.setSubject(reqMap.get("proceedsItem").toString());

        /** 订单金额，精确到小数点后两位 **/
        model.setTotalAmount(reqMap.get("money").toString());

        /** 订单描述 **/
        model.setBody(reqMap.get("subheading").toString());

        /** 业务扩展参数 **/
        //ExtendParams extendParams = new ExtendParams();

        /** 系统商编号，填写服务商的PID，返佣参数传值前提：传值账号需要签约返佣协议，用于isv商户。 **/
        //extendParams.setSysServiceProviderId("2088511****07846");

        /** 花呗分期参数，传值前提：必须有该接口花呗收款准入条件，且需签约花呗分期 **/
        /** 指定可选期数，只支持3/6/12期，还款期数越长手续费越高 **/
        // extendParams.setHbFqNum("3");

        /** 指定花呗分期手续费承担方式，手续费可以由用户全承担（该值为0），也可以商户全承担（该值为100），但不可以共同承担，即不可取0和100外的其他值。 **/
        //extendParams.setHbFqSellerPercent("0");

        //model.setExtendParams(extendParams);

        /** 将业务参数传至request中 **/
        alipayRequest.setBizModel(model);

        /** 注：支付结果以异步通知为准，不能以同步返回为准，因为如果实际支付成功，但因为外力因素，如断网、断电等导致页面没有跳转，则无法接收到同步通知；**/
        /** 同步通知地址，以http或者https开头，支付完成后跳转的地址，用于用户视觉感知支付已成功，传值外网可以访问的地址，如果同步未跳转可参考该文档进行确认：https://opensupport.alipay.com/support/helpcenter/193/201602474937 **/
        alipayRequest.setReturnUrl("");

        /** 异步通知地址，以http或者https开头的，商户外网可以post访问的异步地址，用于接收支付宝返回的支付结果，如果未收到该通知可参考该文档进行确认：https://opensupport.alipay.com/support/helpcenter/193/201602475759 **/
        alipayRequest.setNotifyUrl("http://47.94.170.38:8080/TGP/PaymentRES");

        /**第三方调用（服务商模式），传值app_auth_token后，会收款至授权app_auth_token对应商家账号，如何获传值app_auth_token请参考文档：https://opensupport.alipay.com/support/helpcenter/79/201602494631 **/
        //request.putOtherTextParam("app_auth_token", "传入获取到的app_auth_token值");
        String form = null;
        try {
            /** 调用SDK生成表单form表单 **/
            //form = alipayClient.pageExecute(alipayRequest).getBody();

            /** 调用SDK生成支付链接，可在浏览器打开链接进入支付页面 **/
            form = alipayClient.pageExecute(alipayRequest,"GET").getBody();

            //添加订单
             shareOrderFormMapper.insertShareOrderForm(shareOrderForm);
            //添加订单备注
            //使用GSON工具类转化伟HashMap取值
            HashMap hashMap = getGson().fromJson(jsonObject.toString(), HashMap.class);
            List<String> shareGoodsRemarksList = JSONObject.parseArray(hashMap.get("shareGoodsRemarksList").toString(), String.class);
            for (String shareGoodsRemarkString : shareGoodsRemarksList){
                HashMap shareGoodsRemark = getGson().fromJson(shareGoodsRemarkString, HashMap.class);
                //创建订单商品备注对象
                ShareOrderGoodsRemarks shareOrderGoodsRemarks =new ShareOrderGoodsRemarks();
                shareOrderGoodsRemarks.setOrderId(shareOrderForm.getId());
                shareOrderGoodsRemarks.setRemarksId(Long.parseLong(shareGoodsRemark.get("id").toString()));
                shareOrderGoodsRemarks.setContent(shareGoodsRemark.get("content").toString());
                //增加订单商品备注
                int i = shareOrderGoodsRemarksMapper.insertShareOrderGoodsRemarks(shareOrderGoodsRemarks);

            }
            res.put("code","200");
            res.put("data",form);
            res.put("message","操作成功");
        } catch (Exception e) {
            res.put("code","500");
            res.put("message",e.getMessage());
            e.printStackTrace();
        }

        /** 获取接口调用结果，如果调用失败，可根据返回错误信息到该文档寻找排查方案：https://opensupport.alipay.com/support/helpcenter/93 **/
//        System.out.println(form);
//        response.setContentType("text/javascript;charset=" + "utf-8");

        /** 直接将完整的表单html输出到页面 **/
//        response.getWriter().write(form);
//        response.getWriter().flush();


        return res;
    }

    @Override
    public String PaymentRES(Map<String,String> params) {
        //订单号
        String orderCode = params.get("out_trade_no").toString();
        //支付宝的交易号
        String tradeNo = params.get("trade_no");
        //支付宝的交易状态
        String tradeStatus = params.get("trade_status");
        //在这个方法里面查询一下，看一下这个订单号码是否存在
        ShareOrderForm shareOrderForm = shareOrderFormMapper.selectShareOrderFormByOrderCode(orderCode);
        if(shareOrderForm == null){
            return ("非分账系统的订单,回调忽略");
        }
        //在这里调用枚举类，判断订单是否已经支付
        if(shareOrderForm.getPayStatus()==1){
            return ("支付宝重复调用");
        }
        //这里调用的是支付宝官方的枚举
        //“TRADE_STATUS_TRADE_SUCCESS”是交易完成的意思
        if(tradeStatus.equals("TRADE_SUCCESS")){
            //记录交易的时间，这个字符串是固定的
            shareOrderForm.setPayStatus(1);
            //把订单状态改成已付款
            shareOrderFormMapper.updateShareOrderForm(shareOrderForm);
        }else{
            return "error";
        }
        return "success";
    }

    @Override
    public void doPost(JSONObject params) throws AlipayApiException {
  /*
        out_trade_no	String	特殊可选	64	订单支付时传入的商户订单号,和支付宝交易号不能同时为空。
        trade_no,out_trade_no如果同时存在优先取trade_no	20150320010101001
        trade_no	String	特殊可选	64	支付宝交易号，和商户订单号不能同时为空	2014112611001004680 073956707
        org_pid	String	可选	16	银行间联模式下有用，其它场景请不要使用；
        双联通过该参数指定需要查询的交易所属收单机构的pid;	2088101117952222
        query_options	String[]	可选	1024	查询选项，商户传入该参数可定制本接口同步响应额外返回的信息字段，数组格式。支持枚举如下：trade_settle_info：返回的交易结算信息，包含分账、补差等信息。
        fund_bill_list：交易支付使用的资金渠道。	trade_settle_info
*/
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2");
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", "20150320010101001");
        //bizContent.put("trade_no", "2014112611001004680073956707");
        request.setBizContent(bizContent.toString());
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        if(response.isSuccess()){
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }
    }
    //重置Gson构造器
    public static Gson getGson() {
        Gson gson = new GsonBuilder().registerTypeAdapter(HashMap.class, new JsonDeserializer<HashMap>() {
            @Override
            public HashMap<String, Object> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                HashMap<String, Object> resultMap = new HashMap<>();
                JsonObject jsonObject = json.getAsJsonObject();
                Set<Map.Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
                for (Map.Entry<String, JsonElement> entry : entrySet) {
                    resultMap.put(entry.getKey(), entry.getValue());
                }
                return resultMap;
            }
        }).create();
        return gson;
    }
}
